package cc.wanforme.authtest.config.auth;

import org.springframework.aop.Advisor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.security.authorization.method.AuthorizationInterceptorsOrder;
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
//public class SpringSecurityConfiguration extends WebSecurityConfigurerAdapter{ // ::before springboot-2.7
public class SpringSecurityConfiguration { // ::after springboot-2.7
	
	/** 自定义路径的权限*/
	/* ::before springboot-2.7
	@Override
	public void configure(HttpSecurity http) throws Exception {
		// 默认所有请求不需要认证。
		http
			.authorizeRequests()
			.antMatchers("/**").permitAll();
		
		// 调用 /logout 接口时的处理，不自定义 LogoutSuccessHandler 时，默认会跳转到 /login 接口上
		// 并且自定义的 /logout 接口无效
		//http.logout()
		//.logoutSuccessHandler((request, response, authentication) -> {
		//	//SecurityContextHolder.clearContext(); // 代替下面的调用，去除 session 内的缓存
		//}).invalidateHttpSession(true); 
		
		// 直接禁用内置的注销处理, 旧项目升级迁移需要（有自定义注销逻辑的情况）。
		http.logout().disable();
		
		http.csrf().disable(); //允许跨域伪造请求
		http.cors().disable(); // 允许跨域资源共享
		return http.build();
	}
	*/

	/** ::after springboot-2.7 */
	@Bean
	public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
		// 默认所有请求不需要认证。
		http
			.authorizeRequests()
			.antMatchers("/**").permitAll();
		
		// 调用 /logout 接口时的处理，不自定义 LogoutSuccessHandler 时，默认会跳转到 /login 接口上
		// 并且自定义的 /logout 接口无效
		//http.logout()
		//.logoutSuccessHandler((request, response, authentication) -> {
		//	//SecurityContextHolder.clearContext(); // 代替下面的调用，去除 session 内的缓存
		//}).invalidateHttpSession(true);
		
		// 直接禁用内置的注销处理, 旧项目升级迁移需要（有自定义注销逻辑的情况）。
		http.logout().disable();
		
		http.csrf().disable(); //允许跨域伪造请求
		http.cors().disable(); // 允许跨域资源共享
		return http.build();
	}
	
	// 创建拦截器
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	Advisor hasPermissionAuthorizationMethodInterceptor() {
		HasPermissionAuthorizationManager authorizationManager = new HasPermissionAuthorizationManager();
		AuthorizationManagerBeforeMethodInterceptor interceptor = new AuthorizationManagerBeforeMethodInterceptor(
				AuthUtil.forAnnotations(HasPermission.class), authorizationManager);
		// 顺序就和 @PreAuthorize 的顺序保持一致 
		interceptor.setOrder(AuthorizationInterceptorsOrder.PRE_AUTHORIZE.getOrder());
		return interceptor;
	}

	
}
